"""
Case Type   : cm_install
Case Name   : cm_install指定-X参数路径正确，路径为相对路径
Create At   : 2022/11/15
Owner       : @daiguatutu
Description :
    1: 配置xml文件中的cm相关参数;
    2: 数据库用户下执行cm_install,指定-X参数路径正确，路径为相对路径;
    3: gs_om查看集群状态;
    4: cm_ctl查看集群状态;
    5: 查看数据库用户下进程和定时任务;
Expect      :
    1: 成功
    2: 安装成功
    3: 数据库状态正常
    4: 集群状态正常
    5: om_monitor、cm_agent、cm_server进程存在，有om_monitor的定时任务
History     :
    modified by @daiguatutu at 2023-5-22:添加普通用户对cm包的执行权限
    modified by @ningyali at 2025-4-15:优化用例
    modified by @ningyali at 2025-6-9:优化用例，解决xml路径问题
"""
import os
import unittest

from testcase.utils.ComInstall import CmInstall
from testcase.utils.ComInstall import CmUnInstall
from testcase.utils.Common import Common
from testcase.utils.CommonSH import CommonSH
from testcase.utils.Logger import Logger
from yat.test import Node
from yat.test import macro


class CMInstallCase(unittest.TestCase):
    def setUp(self):
        self.log = Logger()
        self.log.info(f'----{os.path.basename(__file__)} start----')
        self.pri_sh = CommonSH('PrimaryDbUser')
        self.root_nodes = (Node('PrimaryRoot'), Node('Standby1Root'),
                           Node('Standby2Root'))
        self.user_nodes = (Node('PrimaryDbUser'), Node('Standby1DbUser'),
                           Node('Standby2DbUser'))
        self.common = Common()
        self.install_pkg_path = os.path.dirname(macro.DB_SCRIPT_PATH)
        self.cm = CmInstall(self.install_pkg_path, self.pri_sh.node.ssh_user)
        self.cm_tool_path = os.path.join(
            os.path.dirname(macro.DB_INSTANCE_PATH), 'tool', 'tool', 'cm_tool')
        self.xml_relative_path = f'{macro.DB_SCRIPT_PATH}/../' \
                                 f'{os.path.basename(macro.DB_XML_PATH)}'

    def test_install(self):
        text = '----step1:配置xml文件中的cm相关参数;expect:执行成功----'
        self.log.info(text)
        res = self.cm.update_xml_for_cm(*self.root_nodes)
        self.assertGreater(res.count('cmDir'), 1, f'执行失败: {text}')

        text = '----step2:数据库用户下执行cm_install,指定-X参数路径正确，路径为相对路径;expect:安装成功----'
        self.log.info(text)
        ls_cmd = f'cd {self.cm.pkg_path};ls|grep "CM"|grep "tar.gz"'
        self.log.info(ls_cmd)
        ls_res = self.common.get_sh_result(self.user_nodes[0], ls_cmd)
        self.log.info(ls_res)

        param = f"-X {self.xml_relative_path} -e {self.cm.env_path} " \
                f"--cmpkg={os.path.join(self.cm.pkg_path, ls_res.strip())}"
        pwd = macro.COMMON_PASSWD
        install_cmd = f'''cd {self.cm_tool_path};
            expect <<EOF
            set timeout 1200
            spawn ./cm_install {param}
            expect {{{{
                "*ca cert*" {{{{ send "{pwd}\\n"; exp_continue }}}}
                "*ca cert*" {{{{ send "{pwd}\\n" }}}}
                eof
            }}}}''' + '\nEOF'
        install_res = self.common.get_sh_result(self.user_nodes[0], install_cmd)
        self.assertIn('Install CM tool success', install_res, '执行失败:' + text)

        text = '----step3:cm_ctl查看集群状态;expect:查询成功，已安装cm----'
        self.log.info(text)
        show_status = f'source {macro.DB_ENV_PATH};' \
                      f'cm_ctl query -Civdp'
        status_msg = self.common.get_sh_result(self.user_nodes[0], show_status)
        self.assertIn("CMServer State", status_msg, "执行失败:" + text)

        text = '----step4:gs_om查看集群状态;expect:已安装cm----'
        self.log.info(text)
        status_msg = self.pri_sh.get_db_cluster_status('detail')
        self.log.info(status_msg)
        self.assertIn('CMServer State', status_msg, "执行失败:" + text)

        text = '----step5:查看数据库用户下进程和定时任务;' \
               'expect:有om_monitor、cm_agent、cm_server的进程，有定时任务----'
        self.log.info(text)
        show_cmd = "crontab -l;ps ux|grep -v grep|" \
                   "egrep 'cm_server|cm_agent|om_monitor';"
        process_res = self.pri_sh.exec_gs_ssh(show_cmd)
        self.assertIn('bin/cm_server', process_res, "执行失败:" + text)
        self.assertIn('bin/cm_agent', process_res, "执行失败:" + text)
        self.assertIn('om_monitor -L', process_res, "执行失败:" + text)

    def tearDown(self):
        text = '----poststep1:卸载cm;expect:执行成功----'
        self.log.info(text)
        self.un_cm = CmUnInstall(self.install_pkg_path,
                                 self.pri_sh.node.ssh_user)
        res = self.un_cm.cm_uninstall(
            self.user_nodes[0], '--deleteData --deleteBinary')
        self.assertIn('Uninstall CM tool success', res, f'执行失败: {text}')
        self.log.info(f'----{os.path.basename(__file__)} end----')
